package it.unica.informatica.enotes.capture;

import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v7.app.ActionBarActivity;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Chronometer;
import android.widget.ImageButton;
import android.widget.Toast;

import java.io.File;
import java.io.IOException;

import it.unica.informatica.enotes.R;
import it.unica.informatica.enotes.manager.AttachmentsAcquisitionManager;

/**
 * This activity manage all the necessary objects to do a voice recording
 * 
 * @author Mirko Marras 
 */
public class AudioCapture extends ActionBarActivity {
   
   /*********************************************************************************************
    *                                 PARAMETERS OF THE ACTIVITY                                *
    *********************************************************************************************/

   public static final String EXTRA_OUTPUT = "path_to_save";
   public static final String EXTRA_ACTION = "action_to_perform";
   public static final int RECORD_SOUND_ACTION = 1;
   public static final int NO_ACTION = 0; 

   /*********************************************************************************************
    *                                      STATE VARIABLES                                      *
    *********************************************************************************************/

   private static String mFileName = null;
   private static int requestAction = NO_ACTION;
   private static boolean isRecording = false;

   /*********************************************************************************************
    *                             MEDIA RECORDER FOR VOICE RECORDING                            *
    *********************************************************************************************/

   private MediaRecorder mRecorder = null;
   boolean mStartRecording = true;
   
   /*********************************************************************************************
    *                                       VIEW OBJECTS                                        *
    *********************************************************************************************/

   private ImageButton mRecordImageButton = null;
   private ImageButton mSelectImageButton = null;
   private ImageButton mDiscardImageButton = null;
   private Chronometer myChronometer = null;
   
   /*********************************************************************************************
    *                               METHODS OF THE ACTIVITY LIFECYCLE                           *
    *********************************************************************************************/
   
   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_audio_capture);
      getSupportActionBar().setDisplayHomeAsUpEnabled(true);

      /* Get the request type and the path of the file to which store the voice recorded */
      Intent intent = getIntent();
      mFileName = intent.getStringExtra(EXTRA_OUTPUT);
      requestAction = intent.getIntExtra(EXTRA_ACTION, NO_ACTION);
      
      /* If there is an error in the request */
      if(requestAction == NO_ACTION) {
         finish();
      }
      
      /* Initialize all view objects and listeners */
      initializeViews();
   }

   @Override
   public void onPause() {
      super.onPause();
      if(mRecorder != null) {
         changeRecordingState();
      }
   }

   @Override
   public void onBackPressed() {
      if(isRecording) {
         stopRecording();
      }

      File file = new File(mFileName);
      if (file.exists()) {
         file.delete();
      }
      finish();
   }

   @Override
   public boolean onOptionsItemSelected(MenuItem item) {
      switch (item.getItemId()) {
         case android.R.id.home:
            onBackPressed();
            return true;
         default:
            return super.onOptionsItemSelected(item);
      }
   }
   /*********************************************************************************************
    *                          METHODS FOR THE OBJECTS INITIALIZATION                           *
    *********************************************************************************************/

   /**
    * Set all the objects variables to the layout views
    */
   private void initializeViews() {
      /* Retrieve the chronometer used for timing the voice recording */
      myChronometer = (Chronometer) findViewById(R.id.chronometer);

      /* Retrieve the button used to start/end the voice recording */
      mRecordImageButton = (ImageButton) findViewById(R.id.buttonRecording);
      mRecordImageButton.setOnClickListener(new View.OnClickListener() {
         public void onClick(View v) {
            changeRecordingState();
         }
      });

      /* Retrieve the button used to confirm the acquisition of the voice recording and return to NotesActivity */
      mSelectImageButton = (ImageButton) findViewById(R.id.buttonSelect);
      mSelectImageButton.setOnClickListener(new View.OnClickListener() {
         public void onClick(View v) {
            Intent intent = new Intent();
            setResult(RESULT_OK, intent);
            finish();
         }
      });

      /* Retrieve the button used to delete the voice recorded and return to NotesActivity */
      mDiscardImageButton = (ImageButton) findViewById(R.id.buttonDiscard);
      mDiscardImageButton.setOnClickListener(new View.OnClickListener() {
         public void onClick(View v) {
            File file = new File(mFileName);
            if (file.exists()) {
               file.delete();
            }
            finish();
         }
      });
   }

   /*********************************************************************************************
    *                             METHODS TO MANAGE THE VOICE RECORDING                         *
    *********************************************************************************************/

   /**
    * Start the recording of the audio
    */
   private void startRecording() {
      final int CONV_FACTOR = 1000;

      isRecording = true;

      /* Create a new Media Recorder to capture the audio */
      mRecorder = new MediaRecorder();
      
      /* Set listeners to inform of the limits reached by the audio recording */
      mRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
         @Override
         public void onInfo(MediaRecorder mr, int what, int extra) {
            if (what == android.media.MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) {
               stopRecording();
               Toast.makeText(getApplicationContext(), R.string.audio_capture_max_size_reached, Toast.LENGTH_LONG).show();
            } else if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
               stopRecording();
               Toast.makeText(getApplicationContext(), R.string.audio_capture_max_duration_reached, Toast.LENGTH_LONG).show();
            }
         }
      });
      
      /* Set all the parameters of the Media Recorder */
      mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
      mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
      mRecorder.setMaxDuration((int) AttachmentsAcquisitionManager.ALLOWED_MAX_AUDIO_SECONDS * CONV_FACTOR + CONV_FACTOR);
      mRecorder.setMaxFileSize(AttachmentsAcquisitionManager.ALLOWED_MAX_AUDIO_BYTE + CONV_FACTOR);
      mRecorder.setOutputFile(mFileName);
      mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

      /* Prepare and start the Media Recorder */
      try {
         mRecorder.prepare();
      } catch (IOException e) {
         e.printStackTrace();
      }

      mRecorder.start();

      /* Start the chronometer */
      myChronometer.setTextColor(Color.argb(0xff, 0xff, 0x00, 0x00));
      myChronometer.setBase(SystemClock.elapsedRealtime());
      myChronometer.start();

      /* Set the appropriate button during recording */
      mRecordImageButton.setImageDrawable(getResources().getDrawable(R.drawable.ic_action_during_recording));
   }

   /**
    * Stop the recording of the audio
    */
   private void stopRecording() {
      isRecording = false;

      if(mRecorder != null ) {
      /* Stop the chronometer */
         myChronometer.stop();
         myChronometer.setTextColor(Color.argb(0xff, 0xff, 0xff, 0xff));

      /* Stop and release the Media Recorder */
         mRecorder.stop();
         mRecorder.release();
         mRecorder = null;

      /* Show buttons to save or discard the audio recorded */
         mRecordImageButton.setVisibility(View.GONE);
         mSelectImageButton.setVisibility(View.VISIBLE);
         mDiscardImageButton.setVisibility(View.VISIBLE);

      /* Set the appropriate button during not recording */
         mRecordImageButton.setImageDrawable(getResources().getDrawable(R.drawable.ic_action_recording));
      }
   }

   /**
    * Set the state of the recording based on the passed parameter
    * @param start The state of the recording to set
    */
   private void onRecord(boolean start) {
      if (start) {
         startRecording();
      } else {
         stopRecording();
      }

      mStartRecording = !mStartRecording;
   }

   /**
    * Change the state of the recording to RECORDING or NOT_RECORDING
    */
   private void changeRecordingState() {
      /* If the Media Recorder exists, change the state of the recording */
      onRecord(mStartRecording);
   }

}